package com.company.poker.network;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public abstract class AbstractSocketServer {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSocketServer.class);
    private static final Integer DEFAULT_WORKERS = Runtime.getRuntime().availableProcessors() * 2;

    private ServerBootstrap bootstrap;
    private ChannelPipelineFactory pipelineFactory;
    private InetSocketAddress socketAddress;
    private Executor bossThreads;
    private Executor workerThreads;
    private final String host;
    private final int port;
    private final int bossCount;
    private final int workerCount;


    protected AbstractSocketServer(String host, int port, int bossCount, int workerCount) {
        this.host = host;
        this.port = port;
        this.workerCount = workerCount;
        this.bossCount = bossCount;
        this.socketAddress = new InetSocketAddress(host, port);
        this.bossThreads = Executors.newFixedThreadPool(bossCount == 0 ? 1 : bossCount);
        this.workerThreads = Executors.newFixedThreadPool(workerCount == 0 ? DEFAULT_WORKERS : workerCount);
        this.bootstrap = new ServerBootstrap();
        bootstrap.setOption("tcpNoDelay", true);
        bootstrap.setOption("keepAlive", true);
    }

    public void setPipelineFactory(ChannelPipelineFactory pipelineFactory) {
        this.pipelineFactory = pipelineFactory;
    }

    public ChannelPipelineFactory getPipelineFactory() {
        return pipelineFactory;
    }

    protected void init() {
        bootstrap.setFactory(new NioServerSocketChannelFactory(bossThreads, workerThreads));
        bootstrap.setPipelineFactory(pipelineFactory);
    }

    protected void init(ChannelFactory channelFactory, ChannelPipelineFactory pipelineFactory) {
        bootstrap.setFactory(channelFactory);
        bootstrap.setPipelineFactory(pipelineFactory);
    }

    protected void start() {
        bootstrap.bind(socketAddress);
        LOGGER.info("Bind address:"+socketAddress.toString());
    }


}
